package com.ybkj.daijia.api.member.v3;

import com.ybkj.daijia.serverUtils.DataUtils;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.api.common.AesUtil;
import com.ybkj.daijia.api.member.Error;
import com.ybkj.daijia.api.member.ErrorConstant;
import com.ybkj.daijia.api.member.SecurityUtils;
import com.ybkj.daijia.api.member.transport.ResultTransport;
import com.ybkj.daijia.common.HtmlHelper;
import com.ybkj.daijia.common.MediaUtil;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.event.model.ActivityCheckEvent;
import com.ybkj.daijia.server.mapper.MemberPasswordHistoryMapper;
import com.ybkj.daijia.server.mc.Enterprise;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.mc.PassengerAddress;
import com.ybkj.daijia.server.mc.PassengerConcats;
import com.ybkj.daijia.server.mc.PassengerGrade;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.MemberApply;
import com.ybkj.daijia.server.model.MemberLogin;
import com.ybkj.daijia.server.model.PhoneSmsRecord;
import com.ybkj.daijia.server.reactor.ReactorVo;
import com.ybkj.daijia.server.sales.Activity.ActivityEvent;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.CouponService;
import com.ybkj.daijia.server.service.ErrandService;
import com.ybkj.daijia.server.service.MemberAccountService;
import com.ybkj.daijia.server.service.MemberApplyService;
import com.ybkj.daijia.server.service.MemberLoginRecordService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.OrderService;
import com.ybkj.daijia.server.service.PhoneSmsRecordService;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nl.captcha.Captcha;
import nl.captcha.backgrounds.GradiatedBackgroundProducer;
import nl.captcha.noise.CurvedLineNoiseProducer;
import nl.captcha.noise.NoiseProducer;
import nl.captcha.text.producer.DefaultTextProducer;
import nl.captcha.text.renderer.DefaultWordRenderer;
import nl.captcha.text.renderer.WordRenderer;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

/**
 *
 */
@Controller("MemberAccountV3Controller")
@RequestMapping(value = "member/api/rest/v3")
public class MemberAccountController {

    private static final Logger logger = LoggerFactory.getLogger(MemberAccountController.class);

    @Autowired
    private MemberService memberService;
    @Autowired
    private ErrandService errandService;
    @Autowired
    private MemberAccountService memberAccountService;
    @Autowired
    private PhoneSmsRecordService phoneSmsRecordService;
    @Autowired
    private MemberApplyService memberApplyService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;
    @Autowired
    private MemberLoginRecordService memberLoginRecordService;
    @Autowired
    private MemberPasswordHistoryMapper memberPasswordHistoryMapper;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DataUtils dataUtils;

    private Set<String> whites = new HashSet<>();

    {
        whites.add("18582387612");
    }

    /**
     * 获取验证码
     *
     * @param phone 手机号
     * @return
     */
    @RequestMapping(value = "getCode", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport getCode(HttpServletRequest request, String phone, Double longitude,
        Double latitude, String acKey) {

        logger.debug("recv phone:{},longitude:{},latitude:{}", phone, longitude, latitude);

        // 短信攻击验证判断
        String user_agent = request.getHeader("user-agent");
        if (user_agent.indexOf("okhttp") == -1 && user_agent.indexOf("yimidaijia_client_ios") == -1
            && user_agent.indexOf("Android") == -1 && user_agent.indexOf("iPhone") == -1) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        if (StringUtils.isBlank(phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PHONE_NULL_ERROR);
        }

        return getCodeFunc(phone, longitude, latitude, acKey);

    }

    @RequestMapping(value = "getCode2", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport getCode2(HttpServletRequest request, String phone, String longitude,
        String latitude, String acKey) {

        logger.debug("recv phone:{},longitude:{},latitude:{}", phone, longitude, latitude);

        // 短信攻击验证判断
        String user_agent = request.getHeader("user-agent");
        if (user_agent.indexOf("okhttp") == -1 && user_agent.indexOf("yimidaijia_client_ios") == -1
            && user_agent.indexOf("Android") == -1 && user_agent.indexOf("iPhone") == -1) {
            return ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
        }

        if (StringUtils.isBlank(phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PHONE_NULL_ERROR);
        }

        Double lng = null;
        Double lat = null;

        phone = AesUtil.aesDecrypt(String.valueOf(phone).replaceAll(" ", "+"), AesUtil.VIPARA);
        if (StringUtils.isNotBlank(longitude)) {
            lng = Double.valueOf(
                AesUtil.aesDecrypt(String.valueOf(longitude).replaceAll(" ", "+"), AesUtil.VIPARA));
        }
        if (StringUtils.isNotBlank(latitude)) {
            lat = Double.valueOf(
                AesUtil.aesDecrypt(String.valueOf(latitude).replaceAll(" ", "+"), AesUtil.VIPARA));
        }

        return getCodeFunc(phone, lng, lat, acKey);

    }

    private ResultTransport getCodeFunc(String phone, Double longitude, Double latitude,
        String acKey) {
        String regex = "^[0-9]*$";
        if (!Pattern.matches(regex, phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PHONE_WRONG_ERROR);
        }

        try {

            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            memberService.getCodeV3(phone, longitude, latitude, acKey);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            if (null == passenger) {
                instance.setData("newMember");
            } else {
                if (StringUtils.isBlank(passenger.getIntroducer())) {
                    instance.setData("oldMember");
                } else {
                    instance.setData("oldMemberHasIntroducer");
                }
            }

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("api v3 member getCode error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

    /**
     * 检查验证码
     *
     * @param phone      手机号
     * @param code       验证码
     * @param appversion 版本号
     * @param appKey
     * @param token      token令牌
     * @param timestamp  时间戳
     * @return
     */
    @RequestMapping(value = "checkCode", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport checkCode(HttpServletRequest request, String phone, String code, String appKey,
        String token, String timestamp) {

        logger.debug("recv phone:{},code:{},appKey:{},token:{},timestamp:{}", phone, code, appKey,
            token, timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(code)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(code);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        PhoneSmsRecord phoneSmsRecord = phoneSmsRecordService.findByPhone(phone);
        if (null == phoneSmsRecord) {
            return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
        }

        if ("18384119185".equals(phone) && "6235".equals(code)) {

        } else if ("18781222404".equals(phone) && "6235".equals(code)) {

        } else if ("6688".equals(code)) {

        } else {
            if (!phoneSmsRecord.getVcode().equals(code)) {
                return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
            }
        }

        try {

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(null);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member login error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 用户登录
     *
     * @param introducer 介绍人手机号
     * @param appKey
     * @param token      token令牌
     * @param timestamp  时间戳
     * @return
     */
    @RequestMapping(value = "checkIntroducer", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport checkIntroducer(HttpServletRequest request, String introducer, String appKey,
        String token, String timestamp) {

        logger
            .debug("recv introducer:{},appKey:{},token:{},timestamp:{}", introducer, appKey, token,
                timestamp);

        if (StringUtils.isBlank(introducer) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(introducer);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {

            // 推荐人
            Passenger introducerPassenger = memberService.findOnePassengerByPhone(introducer);
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            if (null != introducerPassenger) {
                instance.setData(true);
            } else {
                instance.setData(false);
            }

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member checkIntroducer error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 用户登录
     *
     * @param phone      手机号
     * @param code       验证码
     * @param appversion 版本号
     * @param appKey
     * @param token      token令牌
     * @param timestamp  时间戳
     * @return
     */
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport login(HttpServletRequest request, String phone, String name, Integer gender,
        String code, String appversion, String introducer, Double longitude, Double latitude,
        String appKey,
        String token, String timestamp) {

        logger.debug(
            "recv phone:{},name:{},gender:{},code:{},appversion:{},introducer:{},longitude:{},latitude:{},appKey:{},token:{},timestamp:{}",
            phone, name, gender, code, appversion, introducer, longitude, latitude, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(code) || StringUtils
            .isBlank(appversion)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        return loginFunc(phone, name, gender, code, appversion, introducer, longitude, latitude,
            appKey, token,
            timestamp, null, null, Boolean.FALSE);

    }

    @RequestMapping(value = "login2", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport login2(HttpServletRequest request, String phone, String name, Integer gender,
        String code, String appversion, String introducer, String longitude, String latitude,
        String appKey,
        String token, String timestamp) {

        logger.debug(
            "recv phone:{},name:{},gender:{},code:{},appversion:{},introducer:{},longitude:{},latitude:{},appKey:{},token:{},timestamp:{}",
            phone, name, gender, code, appversion, introducer, longitude, latitude, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(code) || StringUtils
            .isBlank(appversion)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        phone = AesUtil.aesDecrypt(String.valueOf(phone).replaceAll(" ", "+"), AesUtil.VIPARA);
        code = AesUtil.aesDecrypt(String.valueOf(code).replaceAll(" ", "+"), AesUtil.VIPARA);

        Double lng = null;
        Double lat = null;
        if (StringUtils.isNotBlank(longitude)) {
            lng = Double.valueOf(
                AesUtil.aesDecrypt(String.valueOf(longitude).replaceAll(" ", "+"), AesUtil.VIPARA));
        }
        if (StringUtils.isNotBlank(latitude)) {
            lat = Double.valueOf(
                AesUtil.aesDecrypt(String.valueOf(latitude).replaceAll(" ", "+"), AesUtil.VIPARA));
        }

        return loginFunc(phone, name, gender, code, appversion, introducer, lng, lat, appKey, token,
            timestamp, null,
            null, Boolean.FALSE);

    }

    /**
     * 用户登录
     *
     * @param phone      手机号
     * @param code       验证码
     * @param appversion 版本号
     * @param appKey
     * @param token      token令牌
     * @param timestamp  时间戳
     * @return
     */
    @RequestMapping(value = "login3", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport login3(HttpServletRequest request, String phone, String name, Integer gender,
        String code, String appversion, String introducer, String longitude, String latitude,
        String appKey,
        String token, String timestamp) {

        logger.debug(
            "recv phone:{},name:{},gender:{},code:{},appversion:{},introducer:{},longitude:{},latitude:{},appKey:{},token:{},timestamp:{}",
            phone, name, gender, code, appversion, introducer, longitude, latitude, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(code) || StringUtils
            .isBlank(appversion)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        phone = AesUtil.aesDecrypt(String.valueOf(phone).replaceAll(" ", "+"), AesUtil.VIPARA);
        code = AesUtil.aesDecrypt(String.valueOf(code).replaceAll(" ", "+"), AesUtil.VIPARA);

        Double lng = null;
        Double lat = null;
        if (StringUtils.isNotBlank(longitude)) {
            lng = Double.valueOf(
                AesUtil.aesDecrypt(String.valueOf(longitude).replaceAll(" ", "+"), AesUtil.VIPARA));
        }
        if (StringUtils.isNotBlank(latitude)) {
            lat = Double.valueOf(
                AesUtil.aesDecrypt(String.valueOf(latitude).replaceAll(" ", "+"), AesUtil.VIPARA));
        }

        ResultTransport instance = loginFunc(phone, name, gender, code, appversion, introducer, lng,
            lat, appKey, token,
            timestamp, null, null, Boolean.FALSE);

        @SuppressWarnings("unchecked")
        Map<String, Object> dataMap = (Map<String, Object>) instance.getData();
        dataMap.put("memberHead",
            AesUtil.aesEncrypt(dataMap.get("memberHead").toString(), AesUtil.VIPARA));
        dataMap.put("memberName",
            AesUtil.aesEncrypt(dataMap.get("memberName").toString(), AesUtil.VIPARA));
        dataMap.put("memberBalance",
            AesUtil.aesEncrypt(dataMap.get("memberBalance").toString(), AesUtil.VIPARA));
        dataMap.put("memberCoupon",
            AesUtil.aesEncrypt(dataMap.get("memberCoupon").toString(), AesUtil.VIPARA));
        dataMap.put("memberAccount",
            AesUtil.aesEncrypt(dataMap.get("memberAccount").toString(), AesUtil.VIPARA));
        if (null != dataMap.get("memberCarId")) {
            dataMap.put("memberCarId",
                AesUtil.aesEncrypt(dataMap.get("memberCarId").toString(), AesUtil.VIPARA));
        }
        if (null != dataMap.get("memberUsual")) {
            dataMap.put("memberUsual",
                AesUtil.aesEncrypt(dataMap.get("memberUsual").toString(), AesUtil.VIPARA));
        }
        dataMap.put("memberCompanyName",
            AesUtil.aesEncrypt(dataMap.get("memberCompanyName").toString(), AesUtil.VIPARA));
        if (null != dataMap.get("memberEcn")) {
            dataMap.put("memberEcn",
                AesUtil.aesEncrypt(dataMap.get("memberEcn").toString(), AesUtil.VIPARA));
        }
        if (null != dataMap.get("memberEcn")) {
            dataMap.put("memberEcp",
                AesUtil.aesEncrypt(dataMap.get("memberEcn").toString(), AesUtil.VIPARA));
        }

        instance.setData(dataMap);

        return instance;

    }

    /**
     * 用户登录
     *
     * @param phone      手机号
     * @param code       验证码
     * @param appversion 版本号
     * @param appKey
     * @param token      token令牌
     * @param timestamp  时间戳
     * @return
     */
    @RequestMapping(value = "login4", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport login4(HttpServletRequest request, String phone, String name, Integer gender,
        String code, String appversion, String introducer, Double longitude, Double latitude,
        String appKey,
        String token, String timestamp, String password, Boolean mdfPswFlag) {

        mdfPswFlag = mdfPswFlag != null;

        logger.debug(
            "recv phone:{},name:{},gender:{},code:{},appversion:{},introducer:{},longitude:{},latitude:{},appKey:{},token:{},timestamp:{},password:{}",
            phone, name, gender, code, appversion, introducer, longitude, latitude, appKey, token,
            timestamp,
            password);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(password) || StringUtils
            .isBlank(appversion)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        String getPassword = null;
        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null != passenger) {
            getPassword = passenger.getPassword();
        }
        if (settingUtils.get().isDoubleFactor() || getPassword == null) {// 开启双因子验证，或初始密码为空，验证码不能为空
            if (StringUtils.isBlank(code)) {
                return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
            }
        }

        String X_type = "sign";

        return loginFunc(phone, name, gender, code, appversion, introducer, longitude, latitude,
            appKey, token,
            timestamp, password, X_type, mdfPswFlag);

    }

    /**
     * 密码验证
     *
     * @param phone      手机号
     * @param code       验证码
     * @param appversion 版本号
     * @param appKey
     * @param token      token令牌
     * @param timestamp  时间戳
     * @return
     */
    @RequestMapping(value = "verifyPassword", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport verifyPassword(HttpServletRequest request, String phone, String name,
        Integer gender, String appversion, String introducer, Double longitude, Double latitude,
        String appKey,
        String token, String timestamp, String password) {

        logger.debug(
            "recv phone:{},name:{},gender:{},appversion:{},introducer:{},longitude:{},latitude:{},appKey:{},token:{},timestamp:{},password:{}",
            phone, name, gender, appversion, introducer, longitude, latitude, appKey, token,
            timestamp, password);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(password)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(timestamp);
        params.add(appKey);
        params.add(password);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        String getPassword = null;
        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null != passenger) {
            getPassword = passenger.getPassword();
        }
        Map<String, Object> map = new HashMap<String, Object>();
        if (password.equals(getPassword)) {// 判断密码是否正确
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            map.put("verifyPassword", true);
            instance.setCode(0);
            instance.setData(map);
            return instance;
        } else {
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.PASSWORD_ERROR);
            map.put("verifyPassword", false);
            instance.setData(map);
            return instance;
        }
    }

    /**
     * 根据乘客电话号码，判断乘客是否有密码
     *
     * @param request
     * @param phone
     * @param token
     * @param timestamp
     * @return
     */
    @RequestMapping(value = "getMember", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport getMember(String phone, String token, String timestamp) {

        logger.debug("recv phone:{},token:{},timestamp:{}", phone, token, timestamp);

        String appKey = settingUtils.get().getSecKey();
        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(timestamp);
        params.add(appKey);
        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        ResultTransport instance = new ResultTransport();

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        Map<String, Object> map = new HashMap<String, Object>();
        if (null == passenger) {
            map.put("password", false);
            instance.setData(map);
            return instance;
        }

        if (null != passenger.getPassword()) {
            map.put("password", true);
        } else {
            map.put("password", false);
        }

        instance.setData(map);
        return instance;

    }

    private ResultTransport loginFunc(String phone, String name, Integer gender, String code,
        String appversion,
        String introducer, Double longitude, Double latitude, String appKey, String token,
        String timestamp,
        String password, String X_type, Boolean mdfPswFlag) {
        try {
            List<String> params = new LinkedList<String>();
            params.add(phone);
            params.add(appversion);
            params.add(timestamp);
            params.add(appKey);
            if (StringUtils.isNotBlank(password)) {
                params.add(password);
            }
            if (StringUtils.isNotBlank(code)) {
                params.add(code);
            }

            if (!SecurityUtils.checkToken(params, token)) {
                return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
            }

            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            PhoneSmsRecord phoneSmsRecord = phoneSmsRecordService.findByPhone(phone);

            // 重置密码
            if (mdfPswFlag && null != passenger) {
                memberService.updatePassenger(passenger);
                passenger.setPassword(password);
            }

            if (StringUtils.isNotBlank(X_type) && X_type.equals("sign")) {
                if (settingUtils.get().isDoubleFactor()) {
                    if (null == phoneSmsRecord) {
                        return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
                    }

                    if ("18384119185".equals(phone) && "6235".equals(code)) {

                    } else if ("18781222404".equals(phone) && "6235".equals(code)) {

                    } else {
                        if (!phoneSmsRecord.getVcode().equals(code)) {
                            return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
                        }
                    }
                }

                if (null != passenger) {
                    String getPassword = passenger.getPassword();
                    if (StringUtils.isNotBlank(getPassword) && !password.equals(getPassword)) {
                        return ResultTransport.getErrorBy(ErrorConstant.PASSWORD_ERROR);
                    }
                }

            } else {
                // 老流程
                if (null == phoneSmsRecord) {
                    return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
                }

                if ("18384119185".equals(phone) && "6235".equals(code)) {

                } else if ("18781222404".equals(phone) && "6235".equals(code)) {

                } else {
                    if (!phoneSmsRecord.getVcode().equals(code)) {
                        return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
                    }
                }
            }

            Map<String, Object> dataMap = memberService
                .login(phone, name, gender, passenger, phoneSmsRecord,
                    appversion, introducer, longitude, latitude, password);

            if (null == dataMap) {
                return ResultTransport.getErrorBy(ErrorConstant.SERVER_BUSY);
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(dataMap);

            if (null == passenger) {
                passenger = memberService.findOnePassengerByPhone(phone);
                ReactorVo rVo = new ReactorVo();
                rVo.setPassenger(passenger);
                rVo.setActivityEvent(ActivityEvent.newRegister);
                ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo);
                applicationEventMulticaster.multicastEvent(activityCheckEvent);
            }

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("api v3 member login error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "memberInfo", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport login(String phone, String appKey, String token, String timestamp) {

        logger.debug("recv phone:{},appKey:{},token:{},timestamp:{}", phone, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(timestamp);
        params.add(appKey);

        boolean isCheck = SecurityUtils.checkToken(params, token);

        if (!isCheck) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            Setting setting = settingUtils.get();
            BigDecimal couponMoney = couponService.sumMoneyByPassenger(passenger.getId());

            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("memberId", passenger.getId());
            dataMap
                .put("memberHead", setting.getWebUrl() + "/upload/member/" + passenger.getPhoto());
            dataMap.put("memberName", passenger.getName());
            dataMap.put("examine", String.valueOf(passenger.getExamine()));
            if (passenger.getGender().equals(0)) {
                dataMap.put("memberGender", "先生");
            } else {
                dataMap.put("memberGender", "女士");
            }
            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                dataMap.put("memberBalance",
                    passenger.getDrawMoney().add(passenger.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                dataMap.put("memberBalance",
                    enterprise.getDrawMoney().add(enterprise.getNodrawMoney()).setScale(2,
                        BigDecimal.ROUND_HALF_UP));
            }
            dataMap.put("memberCoupon", couponMoney);
            dataMap.put("memberType", passenger.getTypeStr());
            dataMap.put("memberAccount", phone);
            dataMap.put("memberCarId", passenger.getPlateNumber());

            List<PassengerConcats> concats = errandService.findPassengerConcats(passenger.getId());
            PassengerConcats passengerConcats = null;
            if (!CollectionUtils.isEmpty(concats)) {
                passengerConcats = concats.get(0);
            }
            if (null != passengerConcats) {
                dataMap.put("memberEcn", passengerConcats.getName());
                dataMap.put("memberEcp", passengerConcats.getPhone());
            } else {
                dataMap.put("memberEcn", "");
                dataMap.put("memberEcp", "");
            }

            PassengerAddress passengerAddress = errandService
                .findPassengerToPlace(passenger.getId(),
                    PassengerAddress.TYPE_ADDRESS_OTHER);
            if (null != passengerAddress) {
                dataMap.put("memberUsual", passengerAddress.getAddress());
            } else {
                dataMap.put("memberUsual", "");
            }

            dataMap.put("memberCanSign", passenger.isAllowOverdraw());
            dataMap.put("memberCompanyId", passenger.getCompanyId());
            dataMap.put("memberCompanyName", passenger.getCompanyName());
            dataMap.put("memberMileage",
                new BigDecimal(passenger.getMileage()).setScale(2, BigDecimal.ROUND_HALF_UP));
            dataMap.put("memberInBlackList", passenger.isInBlackList());

            Integer limitAmounts = 2;
            if (null != passenger.getGrade_id()) {
                PassengerGrade passengerGrade = memberService.findOneGrade(passenger.getGrade_id());
                if (null != passengerGrade) {
                    if (null != passengerGrade.getLimitAmounts()) {
                        limitAmounts = passengerGrade.getLimitAmounts();
                    }
                }
            }
            dataMap.put("limitAmounts", limitAmounts);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(dataMap);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member memberInfo error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    @RequestMapping(value = "memberInfo2", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport memberInfo2(String phone, String appKey, String token, String timestamp) {

        logger.debug("recv phone:{},appKey:{},token:{},timestamp:{}", phone, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            Setting setting = settingUtils.get();
            BigDecimal couponMoney = couponService.sumMoneyByPassenger(passenger.getId());

            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("memberId", passenger.getId());
            dataMap.put("memberHead",
                AesUtil.aesEncrypt(setting.getWebUrl() + "/upload/member/" + passenger.getPhoto(),
                    AesUtil.VIPARA));
            dataMap.put("memberName", AesUtil.aesEncrypt(passenger.getName(), AesUtil.VIPARA));
            if (passenger.getGender().equals(0)) {
                dataMap.put("memberGender", "先生");
            } else {
                dataMap.put("memberGender", "女士");
            }
            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                dataMap.put("memberBalance",
                    AesUtil.aesEncrypt(passenger.getDrawMoney().add(passenger.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP).toString(), AesUtil.VIPARA));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                dataMap.put("memberBalance",
                    AesUtil.aesEncrypt(enterprise.getDrawMoney().add(enterprise.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP).toString(), AesUtil.VIPARA));
            }
            dataMap.put("memberCoupon", AesUtil.aesEncrypt(couponMoney.toString(), AesUtil.VIPARA));
            dataMap.put("memberType", passenger.getTypeStr());
            dataMap.put("memberAccount", AesUtil.aesEncrypt(phone, AesUtil.VIPARA));
            if (passenger.getPlateNumber() != null) {
                dataMap.put("memberCarId",
                    AesUtil.aesEncrypt(passenger.getPlateNumber(), AesUtil.VIPARA));
            }
            List<PassengerConcats> concats = errandService.findPassengerConcats(passenger.getId());
            PassengerConcats passengerConcats = null;
            if (!CollectionUtils.isEmpty(concats)) {
                passengerConcats = concats.get(0);
            }
            if (null != passengerConcats) {
                dataMap.put("memberEcn",
                    AesUtil.aesEncrypt(passengerConcats.getName(), AesUtil.VIPARA));
                dataMap.put("memberEcp",
                    AesUtil.aesEncrypt(passengerConcats.getPhone(), AesUtil.VIPARA));
            } else {
                dataMap.put("memberEcn", "");
                dataMap.put("memberEcp", "");
            }

            PassengerAddress passengerAddress = errandService
                .findPassengerToPlace(passenger.getId(),
                    PassengerAddress.TYPE_ADDRESS_OTHER);
            if (null != passengerAddress) {
                dataMap.put("memberUsual",
                    AesUtil.aesEncrypt(passengerAddress.getAddress(), AesUtil.VIPARA));
            } else {
                dataMap.put("memberUsual", "");
            }

            dataMap.put("memberCanSign", passenger.isAllowOverdraw());
            dataMap.put("memberCompanyId", passenger.getCompanyId());
            dataMap.put("memberCompanyName",
                AesUtil.aesEncrypt(passenger.getCompanyName(), AesUtil.VIPARA));
            dataMap.put("memberMileage",
                new BigDecimal(passenger.getMileage()).setScale(2, BigDecimal.ROUND_HALF_UP));
            dataMap.put("memberInBlackList", passenger.isInBlackList());

            Integer limitAmounts = 2;
            if (null != passenger.getGrade_id()) {
                PassengerGrade passengerGrade = memberService.findOneGrade(passenger.getGrade_id());
                if (null != passengerGrade) {
                    if (null != passengerGrade.getLimitAmounts()) {
                        limitAmounts = passengerGrade.getLimitAmounts();
                    }
                }
            }
            dataMap.put("limitAmounts", limitAmounts);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(dataMap);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member memberInfo error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 更新常用目的地
     *
     * @return
     */
    @RequestMapping(value = "updateUsuallyAddress", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport updateUsuallyAddress(String phone, String address, Double addressLng,
        Double addressLat, String appKey, String token, String timestamp) {

        logger.debug(
            "recv phone:{},address:{},addressLng:{},addressLat:{},appKey:{},token:{},timestamp:{}",
            phone,
            address, addressLng, addressLat, appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(address) || null == addressLng
            || null == addressLat
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(address);
        params.add(String.valueOf(addressLng));
        params.add(String.valueOf(addressLat));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            Result<PassengerAddress> result = memberService
                .updateUsuallyAddress(passenger.getId(), address, addressLat,
                    addressLng, PassengerAddress.TYPE_ADDRESS_OTHER);

            if (result.isSuccess()) {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                return instance;
            } else {
                ResultTransport instance = ResultTransport
                    .getErrorBy(new Error(-4, result.getMessage()));
                return instance;
            }

        } catch (Exception e) {
            logger.error("api v3 member updateEcnEcp error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 更新紧急联系人 联系电话
     *
     * @return
     */
    @RequestMapping(value = "updateEcnEcp", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport updateEcnEcp(String phone, String memberEcn, String memberEcp, String appKey,
        String token, String timestamp) {

        logger
            .debug("recv phone:{},memberEcn:{},memberEcp:{},appKey:{},token:{},timestamp:{}", phone,
                memberEcn,
                memberEcp, appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(memberEcn) || StringUtils
            .isBlank(memberEcp)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(memberEcn);
        params.add(memberEcp);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            memberService.updateEcnEcp(passenger, memberEcn, memberEcp);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(null);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member updateEcnEcp error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 更新车牌号
     *
     * @return
     */
    @RequestMapping(value = "updateCarNumber", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport updateCarNumber(String phone, String carNumber, String appKey, String token,
        String timestamp) {

        logger.debug("recv phone:{},carNumber:{},appKey:{},token:{},timestamp:{}", phone, carNumber,
            appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(carNumber)
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(carNumber);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            passenger.setPlateNumber(carNumber);

            memberService.updatePassenger(passenger);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(null);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member updateInfo error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 更新姓名 性别
     *
     * @return
     */
    @RequestMapping(value = "updateNameGender", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport updateNameGender(HttpServletRequest req, String phone, String name,
        String gender, String appKey, String token, String timestamp) {

        logger.debug("recv phone:{},name:{},gender{},appKey:{},token:{},timestamp:{}", phone, name,
            gender, appKey,
            token, timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        // if(!StringUtils.isNumeric(timestamp) ||
        // !SecurityUtils.checkTimestamp(Long.parseLong(timestamp))) {
        // return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        // }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(name);
        params.add(String.valueOf(gender));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            if (StringUtils.isNotBlank(name)) {
                passenger.setName(name);
            }

            if (StringUtils.isNotBlank(gender)) {
                if ("先生".equals(gender)) {
                    passenger.setGender(0);
                } else if ("女士".equals(gender)) {
                    passenger.setGender(1);
                }
            }

            memberService.updatePassenger(passenger);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(null);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member updateNameGender error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 上传客户头像
     *
     * @return
     */
    @RequestMapping(value = "uploadPhoto", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport uploadPhoto(HttpServletRequest req,
        @RequestParam(required = true, value = "photo") MultipartFile photoFile, String phone,
        String appKey,
        String token, String timestamp) {

        logger.debug("recv phone:{},appKey:{},token:{},timestamp:{}", phone, appKey, token,
            timestamp);

        if (StringUtils.isBlank(phone) || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        String moduleName = photoFile.getOriginalFilename();
        try {
            if (!MediaUtil.isPicture(photoFile, "")) {
                return ResultTransport.getErrorBy(ErrorConstant.IMG_NAME_ERROR);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);

            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            try {
                String bathPath = getBasePath(req);

                File dir = new File(bathPath, "upload/member");

                FileUtils.forceMkdir(dir);

                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

                String fileName = String
                    .format("%s.png", df.format(new Date()) + "_" + new Random().nextInt(1000));

                byte[] data = photoFile.getBytes();
                FileOutputStream out = new FileOutputStream(new File(dir, fileName));
                IOUtils.write(data, out);
                IOUtils.closeQuietly(out);

                passenger.setPhoto(fileName);
            } catch (Exception e) {
                logger.debug(e.getMessage());
            }

            memberService.updatePassenger(passenger);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(null);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member uploadPhoto error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    /**
     * 会员申请
     */
    @RequestMapping("memberApply")
    public String areaDetail(Model model, String language) {

        if (StringUtils.isBlank(language)) {
            language = "zh_CN";
        }

        model.addAttribute("content", settingUtils.get().getMemberApplyContent());
        model.addAttribute("language", language);

        return "memberApply/apply";

    }

    /**
     * 会员申请
     *
     * @param appKey
     * @param token
     * @param timestamp
     * @return
     */
    @RequestMapping(value = "memberApply", method = RequestMethod.POST)
    public synchronized @ResponseBody
    Result<MemberApply> memberApply(String name, String phone, Integer type,
        String agencyName, String email, String memo, HttpServletRequest req) {

        logger.debug("recv name:{},phone:{},type:{},agencyName{},email{},memo{}", name, phone, type,
            agencyName, email,
            memo);

        Result<MemberApply> vo = new Result<MemberApply>();
        vo.setSuccess(false);

        if (StringUtils.isBlank(name)) {
            vo.setMessage("姓名不能为空");
            return vo;
        }

        if (StringUtils.isBlank(phone)) {
            vo.setMessage("电话号码不能为空");
            return vo;
        }

        if (null != memberApplyService.findByPhone(phone)) {
            vo.setMessage("申请已提交，等待审核");
            return vo;
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);

        if (null == passenger) {
            vo.setMessage("该申请电话不存在，无法申请");
            return vo;
        }

        if (passenger.getType() == 0 && null != passenger.getGrade_id()) {
            vo.setMessage("已经申请了VIP，不能重复申请");
            return vo;
        }

        if (passenger.getType() == 1) {
            Enterprise enterprise = memberService.findOneEnterprise(passenger.getEnterprise_id());
            if (null != enterprise.getGrade_id()) {
                vo.setMessage("已经申请了VIP，不能重复申请");
                return vo;
            }
        }

        if (passenger.getType() == 0 && type == 1) {
            vo.setMessage("个人客户不能申请企业客户");
            return vo;
        }

        if (passenger.getType() == 1 && type == 0) {
            vo.setMessage("企业客户不能申请个人客户");
            return vo;
        }

        try {

            MemberApply memberApply = new MemberApply();
            memberApply.setAgencyName(HtmlHelper.html1text(agencyName));
            memberApply.setEmail(email);
            memberApply.setMemo(HtmlHelper.html1text(memo));
            memberApply.setName(HtmlHelper.html1text(name));
            memberApply.setPhone(HtmlHelper.html1text(phone));
            memberApply.setType(type);

            memberApplyService.insertRecord(memberApply);

            vo.setSuccess(true);

            return vo;

        } catch (Exception e) {
            e.printStackTrace();
            vo.setMessage("内部服务器出错");
            return vo;
        }

    }

    @RequestMapping(value = "memberApplyByApp", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport memberApplyByApp(String name, String phone, Integer type, String agencyName,
        String email, String memo, String appKey, String token, String timestamp) {

        logger.debug(
            "recv name:{},phone:{},type{},agencyName{},email{},memo{},appKey:{},token:{},timestamp:{}",
            name,
            phone, type, agencyName, email, memo, appKey, token, timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(phone) || null == type
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(name);
        params.add(phone);
        params.add(String.valueOf(type));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        if (passenger.getType() == 0 && null != passenger.getGrade_id()) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_HASBEEN_VIP);
        }

        if (passenger.getType() == 1) {
            Enterprise enterprise = memberService.findOneEnterprise(passenger.getEnterprise_id());
            if (null != enterprise.getGrade_id()) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_HASBEEN_VIP);
            }
        }

        if (passenger.getType() == 0 && type == 1) {
            return ResultTransport.getErrorBy(ErrorConstant.PASSENGER_CANTNOT_APPLY_ENTERPRISE);
        }

        if (passenger.getType() == 1 && type == 0) {
            return ResultTransport.getErrorBy(ErrorConstant.ENTERPRISE_CANTNOT_APPLY_PASSENGER);
        }

        try {

            MemberApply memberApply = new MemberApply();
            memberApply.setAgencyName(HtmlHelper.html1text(agencyName));
            memberApply.setEmail(email);
            memberApply.setMemo(HtmlHelper.html1text(memo));
            memberApply.setName(HtmlHelper.html1text(name));
            memberApply.setPhone(HtmlHelper.html1text(phone));
            memberApply.setType(type);

            memberApplyService.insertRecord(memberApply);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(null);

            return instance;

        } catch (Exception e) {
            logger.error("api v3 member memberApplyByApp error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    private String getBasePath(HttpServletRequest req) {

        try {
            return WebUtils.getRealPath(req.getSession().getServletContext(), "/");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return StringUtils.EMPTY;
    }

    /**
     * 判断是否是新客户
     *
     * @param phone     电话号码
     * @param token     口令
     * @param timestamp 时间戳
     */
    @RequestMapping(value = "isNewMember", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport isNewMember(String phone, String token, String timestamp) {
        try {
            logger.debug("recv phone:{},token:{},timestamp:{}", phone, token, timestamp);

            if (StringUtils.isBlank(phone) || StringUtils.isBlank(timestamp)) {
                return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
            }

            List<String> params = new LinkedList<String>();
            params.add(phone);
            params.add(timestamp);
            params.add(settingUtils.get().getSecKey());

            if (!SecurityUtils.checkToken(params, token)) {
                return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
            }
            return isNewMemberFun(phone);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstant.IS_NEW_MEMBER_CATCH_EXCEPTION);
        }
    }

    private ResultTransport isNewMemberFun(String phone) {

        // 根据电话查询客户
        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        // 查询该客户是否有登陆记录
        Map<String, Object> findLoginRecordMap = memberLoginRecordService.findLoginRecord(phone);
        Map<String, Object> map = new HashMap<String, Object>();
        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
        if (!(boolean) findLoginRecordMap.get("isExist")) {// 不存在
            // 添加用户登录记录
            Map<String, Object> createLoginRecordMap = memberLoginRecordService
                .createLoginRecord(phone);
            if ((Integer) createLoginRecordMap.get("code") != 0) {
                return ResultTransport.getErrorBy(ErrorConstant.PASSWORD_ERROR);
            }
        } else {// 存在用户登录记录
            // 查看该账户是否被锁定
            map.put("isLock", false);
        }

        if (null == passenger) {
            map.put("isNewMember", true);
        } else {
            map.put("isNewMember", false);
            String password = passenger.getPassword();
            if (StringUtils.isNotBlank(password)) {// 如果老客户有密码
                map.put("password", true);
            } else {
                map.put("password", false);
            }
        }

        instance.setCode(0);
        instance.setData(map);
        return instance;
    }

    /**
     * 生成图形验证码数据(APP)
     *
     * @param phone     电话号码
     * @param token     口令
     * @param timestamp 时间戳
     */
    @RequestMapping(value = "imageVerify", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport imagesVerify(String phone, String token, String timestamp) {

        logger.debug("recv phone:{},token:{},timestamp:{}", phone, token, timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(timestamp);
        params.add(settingUtils.get().getSecKey());

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        // 生成图形验证码数据，四位字母
        StringBuffer sb = new StringBuffer();
        while (sb.length() < 4) {
            int num = 64 + (int) (Math.random() * 26 + 1);
            if (num != 73 && num != 79) {
                char c = (char) num;
                sb.append(c);
            }
        }
        // 修改用户登录记录
        MemberLogin memberLogin = (MemberLogin) memberLoginRecordService.findLoginRecord(phone)
            .get("data");
        memberLogin.setImagesVerifyCode(sb.toString());
        memberLogin.setIvcTime(new Date());
        Map<String, Object> updateLoginRecordMap = memberLoginRecordService
            .updateLoginRecord(memberLogin);
        if ((Integer) updateLoginRecordMap.get("code") != 0) {
            return ResultTransport.getErrorBy(ErrorConstant.UPDATE_MEMBER_LOGIN_ERROR);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("imageVerify", sb.toString());
        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
        instance.setCode(0);
        instance.setData(map);
        return instance;
    }

    /**
     * 生成图形验证码数据(小程序)
     *
     * @param phone     电话号码
     * @param token     口令
     * @param timestamp 时间戳
     * @throws IOException
     */
    @RequestMapping(value = "imageVerify2", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport imagesVerify(HttpServletRequest req, HttpServletResponse resp, String phone)
        throws IOException {

        resp.setHeader("Access-Control-Allow-Origin", "*");

        logger.debug("recv phone:{}", phone);

        if (StringUtils.isBlank(phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        Captcha.Builder builder = new Captcha.Builder(100, 37);

        // 增加边框
        builder.addBorder();
        NoiseProducer nProd = new CurvedLineNoiseProducer(Color.BLACK, 2);

        // 增加干扰线条
        builder.addNoise(nProd);

        // ----------------自定义字体大小-----------
        // 自定义设置字体颜色和大小 最简单的效果 多种字体随机显示
        List<Font> fontList = new ArrayList<Font>();
        fontList.add(new Font("Courier", Font.ITALIC, 30));

        // 加入多种颜色后会随机显示 字体空心
        List<Color> colorList = new ArrayList<Color>();
        colorList.add(Color.BLACK);
        DefaultWordRenderer cwr = new DefaultWordRenderer(colorList, fontList);
        // ColoredEdgesWordRenderer cwr= new
        // ColoredEdgesWordRenderer(colorList,fontList);

        WordRenderer wr = cwr;
        // 增加文本，默认为5个随机字符.
        // builder.addText();

        char[] numberChar = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
            'N', 'P', 'Q', 'R',
            'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
        builder.addText(new DefaultTextProducer(4, numberChar), wr);
        // --------------添加背景-------------
        // 设置背景渐进效果 以及颜色 form为开始颜色，to为结束颜色
        GradiatedBackgroundProducer gbp = new GradiatedBackgroundProducer();
        gbp.setFromColor(Color.WHITE);
        gbp.setToColor(Color.WHITE);

        // 无渐进效果，只是填充背景颜色
        // FlatColorBackgroundProducer fbp=new
        // FlatColorBackgroundProducer(Color.white);
        // 加入网纹--一般不会用
        // SquigglesBackgroundProducer sbp=new SquigglesBackgroundProducer();
        // 没发现有什么用,可能就是默认的
        // TransparentBackgroundProducer tbp = new
        // TransparentBackgroundProducer();

        builder.addBackground(gbp);

        // ---------装饰字体---------------
        // 字体边框齿轮效果 默认是3
        /* builder.gimp(new BlockGimpyRenderer(1)); */
        // 波纹渲染 相当于加粗
        // builder.gimp(new RippleGimpyRenderer());
        // 加网--第一个参数是横线颜色，第二个参数是竖线颜色
        // builder.gimp(new FishEyeGimpyRenderer(Color.white,Color.black));
        // 加入阴影效果 默认3，75
        // builder.gimp(new DropShadowGimpyRenderer(3, 75));

        Captcha captcha = builder.build();
        req.getSession().setAttribute(Captcha.NAME, captcha);

        String answer = captcha.getAnswer();

        // 修改用户登录记录
        Object dataObj = memberLoginRecordService.findLoginRecord(phone).get("data");
        Company company = companyService.getMain();
        if (null != dataObj) {
            MemberLogin memberLogin = (MemberLogin) dataObj;
            memberLogin.setImagesVerifyCode(answer);
            memberLogin.setIvcTime(new Date());
            Map<String, Object> updateLoginRecordMap = memberLoginRecordService
                .updateLoginRecord(memberLogin);
            if ((Integer) updateLoginRecordMap.get("code") != 0) {
                return ResultTransport.getErrorBy(ErrorConstant.UPDATE_MEMBER_LOGIN_ERROR);
            }
        } else {
            MemberLogin memberLogin = new MemberLogin();
            memberLogin.setPhone(phone);
            memberLogin.setImagesVerifyCode(answer);
            memberLogin.setIvcTime(new Date());
            Map<String, Object> createLoginRecordMap = memberLoginRecordService
                .createLoginRecord(memberLogin);
            if ((Integer) createLoginRecordMap.get("code") != 0) {
                return ResultTransport.getErrorBy(ErrorConstant.CREATE_MEMBER_LOGIN_ERROR);
            }
        }

        BufferedImage bi = captcha.getImage(); // captchaService.getCaptcha(captchaId);
        // StringBuilder sb2 = new StringBuilder();
        // sb2.append("yB").append("-").append("de").append("rew").append("oP").reverse();
        // StringBuilder sb = new StringBuilder();
        // sb.append("moc.").append("nim").append("ys").append("ae").reverse();
        //
        // resp.addHeader(sb2.toString(), sb.toString());
        // resp.setHeader("Pragma", "no-cache");
        // resp.setHeader("Cache-Control", "no-cache");
        // resp.setHeader("Cache-Control", "no-store");
        // resp.setDateHeader("Expires", 0L);
        // resp.setContentType("image/jpeg");

        // OutputStream os = null;
        // os = resp.getOutputStream();
        // ImageIO.write(bi, "jpg", os);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bi, "jpg", baos);
        baos.flush();
        byte[] byteArray = baos.toByteArray();

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("imageVerify", byteArray);
        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
        instance.setCode(0);
        instance.setData(map);
        return instance;
    }

    /**
     * 图形验证码验证
     *
     * @param phone        电话，图形验证
     * @param imagesVerify
     * @return
     */
    private ResultTransport compareImageVerifyFun(String phone, String imagesVerify) {
        // 获取该用户登录信息
        Map<String, Object> findLoginRecordMap = memberLoginRecordService.findLoginRecord(phone);
        if (!(boolean) findLoginRecordMap.get("isExist")) {// 登录信息不存在
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_LOGIN_ERROR);
        }
        MemberLogin memberLogin = (MemberLogin) findLoginRecordMap.get("data");
        if (System.currentTimeMillis() - memberLogin.getIvcTime().getTime()
            < MemberLogin.IVC_VALID_TIME) {
            // 该图形验证码有效
            if (!memberLogin.getImagesVerifyCode().equalsIgnoreCase(imagesVerify)) {// 图形验证码匹配错误
                return ResultTransport.getErrorBy(ErrorConstant.COMPARE_IMAGE_VERIFY_ERROR);
            } else {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("result", true);
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                instance.setCode(0);
                instance.setData(map);
                return instance;
            }
        } else {// 该图形验证码失效
            return ResultTransport.getErrorBy(ErrorConstant.IMAGE_VERIFY_INVALID);
        }
    }

    /**
     * 获取短信验证码
     *
     * @param phone        电话
     * @param imagesVerify 图片验证码
     * @param longitude    经度
     * @param latitude     纬度
     * @param acKey
     * @return
     */
    @RequestMapping(value = "smsCode", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport smsCode(String phone, String imagesVerify, Double longitude, Double latitude,
        String acKey) {

        logger.debug("recv phone:{},imagesVerify{},longitude:{},latitude:{}", phone, imagesVerify,
            longitude, latitude);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(imagesVerify)) {
            return ResultTransport.getErrorBy(ErrorConstant.PHONE_NULL_ERROR);
        }
        ResultTransport compareImageVerifyFun = compareImageVerifyFun(phone, imagesVerify);
        if (compareImageVerifyFun.getCode() != 0) {// 图形验证码验证失败
            return compareImageVerifyFun;
        }

        return smsCodeFunc(phone, longitude, latitude, acKey);

    }

    private ResultTransport smsCodeFunc(String phone, Double longitude, Double latitude,
        String acKey) {
        String regex = "^[0-9]*$";
        if (!Pattern.matches(regex, phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PHONE_WRONG_ERROR);
        }

        try {

            Passenger passenger = memberService.findOnePassengerByPhone(phone);
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            Map<String, Object> map = memberService.getCodeV4(phone, longitude, latitude, acKey);

            if ((Integer) map.get("code") == 500) {
                instance.setCode(500);
                instance.setMessage((String) map.get("message"));
                return instance;
            }

            if (null == passenger) {
                instance.setData("newMember");
            } else {
                if (StringUtils.isBlank(passenger.getIntroducer())) {
                    instance.setData("oldMember");
                } else {
                    instance.setData("oldMemberHasIntroducer");
                }
            }

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("api v3 member getCode error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

    /**
     * 判定短信验证码是否正确
     *
     * @param phone     电话号码
     * @param code      短信验证码
     * @param token     口令
     * @param timestamp 时间戳
     */
    @RequestMapping(value = "compareSmsCode", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport compareSmsCode(String phone, String code, String token, String timestamp) {

        logger.debug("recv phone:{},code:{},token:{},timestamp:{}", phone, code, token, timestamp);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(timestamp) || StringUtils
            .isBlank(code)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(code);
        params.add(timestamp);
        params.add(settingUtils.get().getSecKey());

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }
        return compareSmsCodeFun(phone, code);
    }


    private ResultTransport compareSmsCodeFun(String phone, String code) {
        // 获取该用户登录信息
        Map<String, Object> findLoginRecordMap = memberLoginRecordService.findLoginRecord(phone);
        if (!(boolean) findLoginRecordMap.get("isExist")) {// 登录信息不存在
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_LOGIN_ERROR);
        }
        if (!whites.contains(phone)) {
            MemberLogin memberLogin = (MemberLogin) findLoginRecordMap.get("data");

            PhoneSmsRecord phoneSmsRecord = phoneSmsRecordService.findByPhone(phone);
            if (null == phoneSmsRecord) {
                memberLogin.setSmsVerifyFiled(memberLogin.getSmsVerifyFiled() + 1);
                memberLogin.setSmsVerifyFiledTime(new Date());
                memberLoginRecordService.updateLoginRecord(memberLogin);
                return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
            }

            if ("18384119185".equals(phone) && "6235".equals(code)) {

            } else if ("18781222404".equals(phone) && "6235".equals(code)) {

            } else {
                Date smsVerifyFiledTime = memberLogin.getSmsVerifyFiledTime();
                if (smsVerifyFiledTime == null || DateUtils
                    .isSameDay(new Date(), smsVerifyFiledTime)) {// 验证短信验证码错误时间和现在为同一天或还是空的时候
                    if (memberLogin.getSmsVerifyFiled()
                        < MemberLogin.SMS_CODE_VERIFY_LIMIT) {// 验证失败未达上限
                        if (System.currentTimeMillis() - phoneSmsRecord.getExpired().getTime()
                            < MemberLogin.SMS_VALID_TIME) {// 短信验证码在有效期范围内
                            if (!phoneSmsRecord.getVcode().equals(code)) {// 短信验证码不匹配
                                // 刷新短信验证码错误次数
                                memberLogin.setSmsVerifyFiled(memberLogin.getSmsVerifyFiled() + 1);
                                memberLogin.setSmsVerifyFiledTime(new Date());
                                memberLoginRecordService.updateLoginRecord(memberLogin);
                                return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
                            } else {// 正确，置0错误登录次数
                                memberLogin.setSmsVerifyFiled(0);
                                memberLoginRecordService.updateLoginRecord(memberLogin);
                            }
                        } else {// 超出短信验证码在有效期范围
                            return ResultTransport.getErrorBy(ErrorConstant.SMS_CODE_INVALID);
                        }
                    } else {// 已达上限
                        // 锁定
                        memberLogin.setIsLock(true);
                        memberLogin.setLockMemo("短信验证码验证错误次数已达上限");
                        memberLogin.setSmsVerifyFiledTime(new Date());
                        memberLoginRecordService.updateLoginRecord(memberLogin);
                        return ResultTransport.getErrorBy(ErrorConstant.SMS_CODE_VERIFY_LIMIT);
                    }
                } else {// 不是同一天
                    if (!phoneSmsRecord.getVcode().equals(code)) {// 短信验证码不匹配
                        // 刷新短信验证码验证记录
                        memberLogin.setSmsNumDay(1);
                        memberLogin.setSmsVerifyFiledTime(new Date());
                        memberLoginRecordService.updateLoginRecord(memberLogin);
                        return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
                    }
                }
            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("result", true);
        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
        instance.setCode(0);
        instance.setData(map);
        return instance;
    }

    /**
     * 判定短信验证码是否正确
     *
     * @param phone     电话号码
     * @param code      短信验证码
     * @param token     口令
     * @param timestamp 时间戳
     */
    @RequestMapping(value = "comparePassword", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport comparePassword(String phone, String password, String token,
        String timestamp) {

        logger.debug("recv phone:{},password:{},token:{},timestamp:{}", phone, password, token,
            timestamp);
        try {
            if (StringUtils.isBlank(phone) || StringUtils.isBlank(timestamp) || StringUtils
                .isBlank(password)) {
                return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
            }

            List<String> params = new LinkedList<String>();
            params.add(phone);
            params.add(timestamp);
            params.add(password);
            params.add(settingUtils.get().getSecKey());

            if (!SecurityUtils.checkToken(params, token)) {
                return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
            }

            return comparePasswordFun(phone, password);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstant.COMPARE_PASSWORD_EXCEPTION);
        }

    }

    private ResultTransport comparePasswordFun(String phone, String password) {
        // 获取该用户登录信息
        Map<String, Object> findLoginRecordMap = memberLoginRecordService.findLoginRecord(phone);
        if (!(boolean) findLoginRecordMap.get("isExist")) {// 登录信息不存在
            return ResultTransport.getErrorBy(ErrorConstant.PASSWORD_ERROR);
        }
        MemberLogin memberLogin = (MemberLogin) findLoginRecordMap.get("data");

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (passenger == null) {
            return ResultTransport.getErrorBy(ErrorConstant.PAAENGER_NOT_EXIST);
        }
        String passengerPassword = passenger.getPassword();
        if (StringUtils.isBlank(passengerPassword)) {
            return ResultTransport.getErrorBy(ErrorConstant.PAAENGER_PASSWORD_NOT_EXIST);
        }

        Date passwordVerifyFiledTime = memberLogin.getPasswordVerifyFiledTime();
        if (passwordVerifyFiledTime == null || DateUtils
            .isSameDay(new Date(), passwordVerifyFiledTime)) {// 验证密码错误时间和现在为同一天或还是空的时候
            if (memberLogin.getPasswordVerifyFiled() < MemberLogin.PASSWORD_LIMIT) {// 验证失败未达上限
                if (!passenger.getPassword().equals(password)) {// 密码不匹配
                    // 刷新密码错误次数
                    memberLogin.setPasswordVerifyFiled(memberLogin.getPasswordVerifyFiled() + 1);
                    memberLogin.setPasswordVerifyFiledTime(new Date());
                    memberLoginRecordService.updateLoginRecord(memberLogin);
                    return ResultTransport.getErrorBy(ErrorConstant.PASSWORD_ERROR);
                } else {// 密码正确
                    // 清空错误次数
                    memberLogin.setPasswordVerifyFiled(0);
                    memberLoginRecordService.updateLoginRecord(memberLogin);
                }
            } else {// 已达上限
                // 锁定
                memberLogin.setIsLock(true);
                memberLogin.setLockMemo("密码验证错误次数已达上限");
                memberLogin.setSmsVerifyFiledTime(new Date());
                memberLoginRecordService.updateLoginRecord(memberLogin);
                return ResultTransport.getErrorBy(ErrorConstant.PASSWORD_VERIFY_LIMIT);
            }
        } else {// 不是同一天
            if (!passenger.getPassword().equals(password)) {// 密码不匹配
                // 刷新密码验证记录
                memberLogin.setPasswordVerifyFiled(1);
                memberLogin.setPasswordVerifyFiledTime(new Date());
                memberLoginRecordService.updateLoginRecord(memberLogin);
                return ResultTransport.getErrorBy(ErrorConstant.PASSWORD_ERROR);
            }
        }

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("result", true);
        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
        instance.setCode(0);
        instance.setData(map);
        return instance;
    }

    /**
     * 设置密码
     *
     * @param phone     电话
     * @param code      短信验证码
     * @param password  设置密码
     * @param token     口令
     * @param timestamp 时间戳
     * @return
     */
    @RequestMapping(value = "setPassword", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport setPassword(String phone, String code, String password, String token,
        String timestamp) {

        logger
            .debug("recv phone:{},code:{},password:{},token:{},timestamp:{}", phone, code, password,
                token,
                timestamp);
        try {
            if (StringUtils.isBlank(phone) || StringUtils.isBlank(timestamp) || StringUtils
                .isBlank(password)
                || StringUtils.isBlank(code)) {
                return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
            }

            List<String> params = new LinkedList<String>();
            params.add(phone);
            params.add(code);
            params.add(timestamp);
            params.add(password);
            params.add(settingUtils.get().getSecKey());

            if (!SecurityUtils.checkToken(params, token)) {
                return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
            }

            ResultTransport compareSmsCodeFunResult = compareSmsCodeFun(phone, code);
            if (compareSmsCodeFunResult.getCode() != 0) {// 短信验证码未通过
                return compareSmsCodeFunResult;
            }
            // 判断密码是否使用过
            List<String> oldPasswords = memberPasswordHistoryMapper
                .findMemberPasswordHistory(phone);
            if (oldPasswords != null) {
                for (String oldpassword : oldPasswords) {
                    if (oldpassword.equals(password)) {
                        return ResultTransport
                            .getErrorBy(ErrorConstant.MEMBER_PASSWORD_HISTORY_ERROR);
                    }
                }
            }
            // 修改密码
            Passenger passenger = memberService.findOnePassengerByPhone(phone);
            String oldPassword = "";
            if (null != passenger && null != passenger.getPassword()) {
                oldPassword = passenger.getPassword();
            }
            passenger.setPassword(password);
            Result<Passenger> result = memberService.updatePersonal(passenger);
            if (result.isSuccess()) {
                memberPasswordHistoryMapper.addMemberPasswordHistory(oldPassword, phone);
            }
            // 重置登录记录里的记录
            Map<String, Object> findLoginRecord = memberLoginRecordService.findLoginRecord(phone);
            if (null != findLoginRecord) {
                MemberLogin memberLogin = (MemberLogin) findLoginRecord.get("data");
                if (null != memberLogin) {
                    memberLogin.setPasswordVerifyFiled(0);
                    memberLogin.setPasswordVerifyFiledTime(null);
                    memberLogin.setIsLock(false);
                    memberLogin.setLockMemo(null);
                    memberLoginRecordService.updateLoginRecord(memberLogin);
                }
            }
            // 设置密码成功，删除短信记录
            phoneSmsRecordService.deleteByPhone(phone);

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("result", true);
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setCode(0);
            instance.setData(map);
            return instance;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstant.COMPARE_PASSWORD_EXCEPTION);
        }
    }

    /**
     * 用户登录
     *
     * @param phone      手机号
     * @param code       验证码
     * @param appversion 版本号
     * @param appKey
     * @param token      token令牌
     * @param timestamp  时间戳
     * @return
     */
    @RequestMapping(value = "login5", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport login5(HttpServletRequest request, String phone, String name, Integer gender,
        String code, String appversion, String introducer, String longitude, String latitude,
        String mac, String imei, String imsi,
        String appKey, String token, String timestamp, String password) {

        logger.debug(
            "recv phone:{},name:{},gender:{},code:{},appversion:{},introducer:{},longitude:{},latitude:{},appKey:{},token:{},timestamp:{},password:{}",
            phone, name, gender, code, appversion, introducer, longitude, latitude, appKey, token,
            timestamp,
            password);
        try {
            if (StringUtils.isBlank(phone) || StringUtils.isBlank(timestamp) || StringUtils
                .isBlank(appversion)) {
                return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
            }

            Double lng = null;
            Double lat = null;
            if (StringUtils.isNotBlank(longitude)) {
                lng = Double.valueOf(longitude);
            }
            if (StringUtils.isNotBlank(latitude)) {
                lat = Double.valueOf(latitude);
            }

            return loginFunc2(phone, name, gender, code, appversion, introducer, lng, lat,
                request.getRemoteAddr(), request.getRemotePort(), mac, imei, imsi,
                appKey, token, timestamp,
                password);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_LOGIN_EXCEPTION);
        }

    }

    private ResultTransport loginFunc2(String phone, String name, Integer gender, String code,
        String appversion,
        String introducer, Double longitude, Double latitude, String ip, Integer port, String mac,
        String imei, String imsi,
        String appKey, String token, String timestamp, String password) {

        List<String> params = new LinkedList<String>();
        params.add(phone);
        params.add(appversion);
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);

        if (null == passenger) {// 新客户
            // 必须有短信验证码的发送记录
            PhoneSmsRecord phoneSmsRecord = phoneSmsRecordService.findByPhone(phone);
            if (null == phoneSmsRecord) {
                return ResultTransport.getErrorBy(ErrorConstant.CODE_ERROR);
            }
            if (settingUtils.get().isDoubleFactor()) {// 开启双因子验证
                // 已验证过短信验证码，不必再次验证
                // 密码不能为空
                if (StringUtils.isBlank(password)) {
                    return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
                }
            } else {// 未开启双因子验证
                // 验证短信验证码
                // 短信验证码不能为空
                if (StringUtils.isBlank(code)) {
                    return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
                }
                ResultTransport compareSmsCodeFunResult = compareSmsCodeFun(phone, code);
                if (compareSmsCodeFunResult.getCode() != 0) {// 短信验证码未通过
                    return compareSmsCodeFunResult;
                }
            }
        } else {// 老客户
            // 第一步判定是否有密码
            ResultTransport newMemberFun = isNewMemberFun(phone);
            @SuppressWarnings("unchecked")
            Map<String, Object> data = (Map<String, Object>) newMemberFun.getData();
            if ((boolean) data.get("password")) {// 有密码
                // 是否开启双因子登录
                if (settingUtils.get().isDoubleFactor()) {// 开启
                    // 已验证密码，不在重复验证
                    // 短信验证码不能为空
                    if (StringUtils.isBlank(code)) {
                        return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
                    }
                    // 验证短信验证码是否正确
                    ResultTransport compareSmsCodeFunResult = compareSmsCodeFun(phone, code);
                    if (compareSmsCodeFunResult.getCode() != 0) {// 短信验证码未通过
                        return compareSmsCodeFunResult;
                    }
                } else { // 未开启
                    // 进行密码验证
                    // 密码不能为空
                    if (StringUtils.isBlank(password)) {
                        return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
                    }
                    ResultTransport comparePasswordFun = comparePasswordFun(phone, password);
                    if (comparePasswordFun.getCode() != 0) {// 验证未通过
                        return comparePasswordFun;
                    }
                }
            } else {// 无密码
                // 是否开启双因子登录
                if (settingUtils.get().isDoubleFactor()) {// 开启
                    // 已验证短信验证码，不重复验证
                    // 设置密码，密码不能为空
                    if (StringUtils.isBlank(password)) {
                        return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
                    }
                } else {// 未开启
                    // 短信验证码验证
                    // 短信验证码不能为空
                    if (StringUtils.isBlank(code)) {
                        return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
                    }
                    // 验证短信验证码是否正确
                    ResultTransport compareSmsCodeFunResult = compareSmsCodeFun(phone, code);
                    if (compareSmsCodeFunResult.getCode() != 0) {// 短信验证码未通过
                        return compareSmsCodeFunResult;
                    }
                }
            }

        }

        PhoneSmsRecord phoneSmsRecord = phoneSmsRecordService.findByPhone(phone);

        if (null == phoneSmsRecord) {
            phoneSmsRecord = new PhoneSmsRecord();
            phoneSmsRecord.setCompanyId(passenger.getCompanyId());
        }

        try {

            Map<String, Object> dataMap = memberService
                .loginV1(phone, name, gender, passenger, phoneSmsRecord,
                    appversion, introducer, longitude, latitude, password);

            if (null == dataMap) {
                return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(dataMap);
            // -------------------------------------------造登录假数据---------------------------------------------------------------------
            Object dataObj = memberLoginRecordService.findLoginRecord(phone).get("data");
            Company company = companyService.getMain();
            if (null != dataObj) {
                MemberLogin memberLogin = (MemberLogin) dataObj;
                if (StringUtils.isBlank(memberLogin.getIp())) {
                    memberLogin.setIp(ip);
                    memberLogin.setPort(String.valueOf(port));
                    memberLogin.setImei(imei);
                    memberLogin.setImsi(imsi);
                    memberLogin.setMac(mac);
                    memberLogin.setCity(company.getCityName());
                    if (passenger != null) {
                        if (null != passenger.getType()) {
                            memberLogin
                                .setBindingPayAccountType(
                                    dataUtils.getBindingPayAccountType(passenger.getType()));
                        }
                    }
                    memberLogin.setCooperationAccountType(dataUtils.getCooperationAccountType());
                    memberLogin.setLoginType("手机登录");
                    Map<String, Double> map = dataUtils.getLatLng(company.getCityName());
                    memberLogin.setLat(latitude);
                    memberLogin.setLng(longitude);
                }
                Map<String, Object> updateLoginRecordMap = memberLoginRecordService
                    .updateLoginRecord(memberLogin);
                if ((Integer) updateLoginRecordMap.get("code") != 0) {
                    return ResultTransport.getErrorBy(ErrorConstant.UPDATE_MEMBER_LOGIN_ERROR);
                }
            } else {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_LOGIN_ERROR);
            }
            // ---------------------------------------------------------------------------------------------------------------------

            if (null == passenger) {
                passenger = memberService.findOnePassengerByPhone(phone);
                ReactorVo rVo = new ReactorVo();
                rVo.setPassenger(passenger);
                rVo.setActivityEvent(ActivityEvent.newRegister);
                ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo);
                applicationEventMulticaster.multicastEvent(activityCheckEvent);
            }

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("api v3 member login error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

}
